package com.ikas.autumn.iec104.module.iec.asdudataframe;

import com.ikas.autumn.iec104.module.iec.apdumodel.Apdu;
import com.ikas.autumn.iec104.module.iec.apdumodel.Asdu;
import com.ikas.autumn.iec104.module.iec.apdumodel.Vsq;
import com.ikas.autumn.iec104.module.iec.asdudataframe.typemodel.IeBoolean;
import com.ikas.autumn.iec104.module.iec.asdudataframe.typemodel.IeProofreadTime;
import com.ikas.autumn.iec104.module.iec.asdudataframe.typemodel.InformationBodyAddress;
import com.ikas.autumn.iec104.module.iec.exception.Iec104Exception;
import com.ikas.autumn.iec104.module.iec.nettyconfig.TechnicalTerm;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

/**
 * 单点长时标
 *
 * @author xiuwei
 * @date 2022/03/17
 */
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@Data
public class BooleanWithTimeType  extends  AbstractDataFrameType{

    private List<InformationBodyAddress> addresses = new ArrayList<>();

    private List<BooleanWithTime> datas = new ArrayList<>();
    /**
     * TYPEID
     */
    public static final int TYPEID = TechnicalTerm.SINGEL_POINT_TIME_TYPE;


    @Override
    public void loadByteBuf(ByteBuf is, Vsq vsq) {
        try {
            if (vsq.getSq() == 0) {
                for (int i = 0; i < vsq.getNum(); i++) {
                    addresses.add(new InformationBodyAddress(is));
                    datas.add(new BooleanWithTime(is));
                }
            } else {
                addresses.add(new InformationBodyAddress(is));
                for (int i = 0; i < vsq.getNum(); i++) {
                    datas.add(new BooleanWithTime(is));
                }
            }
        } catch (Iec104Exception e) {
            if (e.getCode() == 3301) {
                return;
            }
        }
    }
    @AllArgsConstructor
    @Data
    public static class BooleanWithTime{

        IeBoolean value;
        IeProofreadTime time;

        public BooleanWithTime(ByteBuf is) throws Iec104Exception {
            this.value = new IeBoolean(is);
            this.time = new IeProofreadTime(is);
        }
    }

    @Override
    public void encode(List<Byte> buffer) {
    }

    @Override
    public Asdu generateBack() {
        Asdu asdu = new Asdu();
        asdu.setTypeId(TYPEID);
        asdu.setDataFrame(this);
        asdu.getVsq().setSq(this.addresses.size() == 1 ? 1 : 0);
        asdu.getVsq().setNum(this.datas.size());
        asdu.setOriginatorAddress(0);
        asdu.setCommonAddress(1);
        return asdu;
    }

    @Override
    public byte[][] handleAndAnswer(Apdu apdu) throws Exception {
        return new byte[0][];
    }


    @Override
    public String toString() {
        StringBuilder s = new StringBuilder("单点带时标\n");
        if (addresses.size() == 1) {
            s.append("连续寻址\n");
            s.append(addresses.get(0).toString()).append("\n");
            int d = 0;
            for (BooleanWithTime data : datas) {
                s.append("点位：").append(addresses.get(0).getAddress() + (d++)).append(",");
                s.append("时间为：").append(data.getTime());
                s.append("值为 ：").append(data.getValue()).append(";");
            }

        } else {
            int f = 0;
            for (BooleanWithTime data : datas) {
                s.append("点位：").append(addresses.get(f++).toString()).append(",");
                s.append("时间为：").append(data.getTime());
                s.append("值为 ：").append(data.getValue()).append(";");
            }
        }
        return s.toString();
    }
}
